The Let's Play Archive

EXAPUNKS

by Carbon dioxide

Part 44: Bloodlust Online

Part 44 - Bloodlust Online

=== Trash World Inbox ===

silentsnack posted:

You can speed things up a bit by initially collecting only the hostnames and using a shortened sorting method that only takes the lowest value instead of bothering with reordering the list each time; while that sort routine searches for the next host ID, a separate EXA builds the actual output file by retrieving the #NERV value from each host in sequence.
code:
REPL TRAVERSE
MAKE
@REP 12
NOOP
@END


MARK LIST_NODES
COPY M F
ADDI X 1 X
TEST MRD
TJMP LIST_NODES

MODE
REPL COMPILER
SEEK -999
JUMP SORT

MARK NEXT
NOOP
GRAB 400;GRAB SUCCESS?
COPY X M;SMALLEST HOST#
MARK SORT
COPY F X

SEEK -1
VOID F
MARK COMPARE
@REP 6
REPL NEXT;EOF=CRASH
TEST F > X
TJMP COMPARE
SEEK -1
COPY F T
SEEK -1
COPY X F
COPY T X
@END
JUMP COMPARE


MARK COMPILER
MAKE
COPY X T;NODE COUNT
MARK DATA
COPY M X;HOST# FROM SORT
MODE
REPL TRAVERSE
SUBI T 1 T
COPY X F
COPY M F;NERV DATA
MODE
TJMP DATA
HALT


MARK TRAVERSE
LINK 800
REPL 11
REPL HOST

MARK 7A
REPL 13
MARK 7
LINK -3
REPL 7
REPL 9A
JUMP HOST

MARK 9A
REPL 11
MARK 9
LINK -1
REPL 7A
REPL 9
JUMP HOST

MARK 11
LINK 1
REPL 7A
REPL 11
JUMP HOST

MARK 13
LINK 3
REPL 9A

REPL 13
;JUMP HOST

MARK HOST
TJMP NERV
COPY #NERV T;FILTER
HOST M
MARK NERV
HOST T
TEST T = X
DIVI #NERV T M
575/129/192 and a modified version with slight tweaks runs 2631/67/192
Very nice. The shortened sorting method also removed the lowest value from the file every round, making the sorting go faster and faster. Also, those tests and jumps at the very bottom are a neat combination. First round, when MARK HOST is reached T is still 0, so the HOST is copied if the #NERV exists. The #NERV itself is never copied because X is also 0 and by that time the HOST sits in T. The second time, when looking for the right host from the sorting method, T contains a value so sending the HOST is skipped, and then the #NERV is only sent if the host name actually matches the value in X. Only a few lines to handle a lot of logic.


=== Bloodlust Online ===


OST: Exapunks

I don't get nearly enough opportunities to link to the title theme. Welcome to the post-game.




Everything looks much the same. There is nothing new to do in the main assignment list, but a new task tabs has appeared in Chatsubo.



The actual chat is still disconnected but it looks like I got a bunch of tasks to do with or for our chat friends.

This is actually the point where I stopped playing during my initial playthrough. From here on out, the LP is mostly blind. All I know is that the puzzles won't get any easier.

Let's just start with the top one, Bloodlust Online with mutex8021.



I think 1998 in the description is the year. I guess my hacking is just to cheat at games now?


OST: Leave No Trace

No talks with Ember, I just jump right in.

The assignment:
- Each host contains an item listing (file 200) that lists all of the items in that location (ID, type, and state).
- First, locate mutex8021's hideout by finding the TALISMAN (file 300). Then find the MAP in the hideout and use it to locate the target host: the secret vampire lair. Next, travel to the target host, disconnect the vampire players by terminating their EXAs, set the DOOR to UNLOCKED and copy the SAFE combination to the CLOCK so that mutex8021 can read it and empty the safe.
- Note that the door to mutex8021's hideout will always be UNLOCKED.


Woah, that's a lot of steps. I'll have to take it bit by bit.
code:
;XA

GRAB 300
COPY F M

;XB

LINK 800
COPY M X
COPY 806 T
MARK CREATELP
MODI -1 T T
REPL GOFIND
JUMP CREATELP

MARK GOFIND
LINK T
GRAB 200
SEEK 1

MARK FIND
TEST F = X
TJMP FOUNDTALISMAN
SEEK 2
JUMP FIND

MARK FOUNDTALISMAN
For now, XA can just handle the keywords file. XB loads the TALISMAN keyword into X, then from 805 down to 1 it will try to link to every host. That'll take a while and there's nothing below 800, but it saves a lot of lines as compared to writing out the 800-805 cases. The REPLs grab file 200. They'll die if they reach EOF without finding the TALISMAN, so one will survive and jump to FOUNDTALISMAN.




XA just has one additional COPY F M to send MAP. This is read by this surviving instance of XB, which will look for it in the same file. The "state" of the MAP is the name of the host that has the vampires, so the next step is to go find it.

code:
;XA

GRAB 300
COPY F M
COPY F M

;XB

LINK 800
COPY M X
COPY 806 T
MARK CREATELP
MODI -1 T T
REPL GOFIND
JUMP CREATELP

MARK GOFIND
LINK T
GRAB 200
SEEK 1

MARK FIND
TEST F = X
TJMP FOUNDTALISMAN
SEEK 2
JUMP FIND

MARK FOUNDTALISMAN
COPY M X
SEEK -9999
SEEK 1
MARK FINDMAP
TEST F = X
TJMP FOUNDMAP
SEEK 2
JUMP FINDMAP

MARK FOUNDMAP
COPY F X
REPL FINDTARGET
HALT


MARK FINDTARGET
LINK -1

COPY 806 T
MARK CREATELP2
MODI -1 T T
REPL GOFINDTARGET
JUMP CREATELP2

MARK GOFINDTARGET
LINK T
HOST T
TEST T = X
DIVI 1 T T ;HLT IF FALSE
@REP 5
KILL
@END
GRAB 200
Once the XB that found the TALISMAN also finds the map, it stores the location of the target in X. It then makes a REPL that goes looking for the target. The original XB instance just HALTs for now, but I kept it because I'll be needing it to grab the UNLOCKED instance from mutex8021's door. The REPL does much the same as before (it's slow but easy to code, and there's plenty of space in the central host anyway), then each REPL checks if it's in the right host. If so, it does a bunch of KILLs, killing all vampires, but also our own EXA which might still be trying to find the TALISMAN over there. That way the new one can GRAB 200 to do the final steps.

In case you were wondering, the files that the other EXAs are holding are their character's inventories. For instance, one of the vampires has a black trench coat, sunglasses, and flask of blood.

To find UNLOCKED, I add another COPY F M to XA, and replace that HALT in XB with:
code:
COPY M X
SEEK -9999
SEEK 1
MARK FINDUNLOCKED
TEST F = X
TJMP FOUNDUNLOCKED
SEEK 2
JUMP FINDUNLOCKED

MARK FOUNDUNLOCKED
COPY X M
COPY F M
HALT
Once again the same search algorithm. You know, it would be really nice if EXAs had a return statement or something so I could program a procedure once and call it multiple times. But to do so you need at least one extra unit of storage to remember where it left off and I'm already using X, T and F, so copy-pasting code is just easier.

I copy both the DOOR and UNLOCKED keywords to M, because the target EXA will need them.

The target EXA (at the bottom of XB), needs yet another copy of the search function to unlock the door:
code:
COPY M X
SEEK 1
MARK FINDLOCKED
TEST F = X
TJMP FOUNDLOCKED
SEEK 2
JUMP FINDLOCKED

MARK FOUNDLOCKED
COPY M F
Then, it needs to repeat that twice more to find the SAFE and the CLOCK so it can write the safe combination to the clock.

And that is the working solution.
code:
; XA
GRAB 300
COPY F M
COPY F M
COPY F M

COPY 24 T
MARK WAIT
SUBI T 1 T
TJMP WAIT

COPY F M
COPY M X
COPY F M
COPY X M

;XB 

LINK 800
COPY M X
COPY 806 T
MARK CREATELP
MODI -1 T T
REPL GOFIND
JUMP CREATELP

MARK GOFIND
LINK T
GRAB 200
SEEK 1

MARK FIND
TEST F = X
TJMP FOUNDTALISMAN
SEEK 2
JUMP FIND

MARK FOUNDTALISMAN
COPY M X
SEEK -9999
SEEK 1
MARK FINDMAP
TEST F = X
TJMP FOUNDMAP
SEEK 2
JUMP FINDMAP

MARK FOUNDMAP
COPY F X
REPL FINDTARGET

COPY M X
SEEK -9999
SEEK 1
MARK FINDUNLOCKED
TEST F = X
TJMP FOUNDUNLOCKED
SEEK 2
JUMP FINDUNLOCKED

MARK FOUNDUNLOCKED
COPY X M
COPY F M
HALT

MARK FINDTARGET
LINK -1

COPY 806 T
MARK CREATELP2
MODI -1 T T
REPL GOFINDTARGET
JUMP CREATELP2

MARK GOFINDTARGET
LINK T
HOST T
TEST T = X
DIVI 1 T T ;HLT IF FALSE
@REP 5
KILL
@END
GRAB 200

COPY M X
SEEK 1
MARK FINDLOCKED
TEST F = X
TJMP FOUNDLOCKED
SEEK 2
JUMP FINDLOCKED

MARK FOUNDLOCKED
COPY M F

COPY M X
SEEK -9999
SEEK 1
MARK FINDSAFE
TEST F = X
TJMP FOUNDSAFE
SEEK 2
JUMP FINDSAFE

MARK FOUNDSAFE
COPY F M

COPY M X
SEEK -9999
SEEK 1
MARK FINDCLOCK
TEST F = X
TJMP FOUNDCLOCK
SEEK 2
JUMP FINDCLOCK

MARK FOUNDCLOCK
COPY M F
2485/99/19.
XA sends the TALISMAN, MAP and DOOR and then waits for a while.
XB goes looking for the TALISMAN, then finds the MAP and makes a REPL to go locate the target. The XB in mutex8021's hideout continues to find the DOOR and then sends DOOR and UNLOCKED on M. The XB REPL in the target kills the vampires, then uses the data from the first XB to unlock the door. XA has been timed to start sending as soon as XB is done with M. It sends the SAFE so the target EXA can get the combination, then stores the safe's combination for a bit and sends the CLOCK, giving the target EXA the space to find the clock in the file. Finally, it sends the combination again so the target EXA can write it.

Top percentiles are 118, 71, and 11.

With this current solution, there's a simple way to lower the cycle count significantly. When the XB in mutex8021's hideout is done, the XB in the target is still doing its thing. So the mutex8021 EXA has cycles to spare.

Just use that to KILL all those EXAs in the center host that are taking ages to loop down to zero. Replace the HALT after FOUNDUNLOCKED with
code:
DROP
LINK -1
@REP 5
KILL
@END
HALT
for a score of 147/106/25. Much better.

At a guess, the approach for the top percentile cycles involves some parallellism. For instance, an EXA could already go check which hosts have a SAFE and dismiss the others as targets.


To get the lowest activity, I'll start by removing unnecessary kills. Instead of those 5 KILLs for looping EXAs above, let's finally unroll the REPL loops:
code:
@REP 5
COPY 80@{0,1} T
REPL GOFIND
@END
COPY 805 T

MARK GOFIND
and the same for the GOFINDTARGET. This code runs at 152/111/19. Better activity, but a couple extra lines and cycles compared to my previous solution.

The other activity improvement is to send only one EXA into each host. That means the target finding logic needs to happen entirely through M.

In my attempts to get this working, I ran into timing issues with mutex8021's hideout EXA sending the target directly to the seeking EXAs. So, instead, I decided to have all communication go through XA.
code:
;XA

GRAB 300
COPY F M ; TALISMAN
COPY F M ; MAP
COPY M X ; TARGET

COPY F M ; DOOR
COPY M T ; UNLOCKED

@REP 5
COPY X M ; TARGET
@END

SEEK -1
COPY F M ; DOOR AGAIN
COPY T M ; UNLOCKED

COPY F M ; SAFE
COPY M X ; COMBINATION
COPY F M ; CLOCK
COPY X M ; COMBINATION

;XB

LINK 800
COPY M X

@REP 5
COPY 80@{0,1} T
REPL GOFIND
@END
COPY 805 T

MARK GOFIND
LINK T
GRAB 200
SEEK 1

MARK FIND
TEST F = X
TJMP FOUNDTALISMAN
SEEK 2
TEST EOF
FJMP FIND

; NOT MUTEX; TARGET?

HOST X

COPY 29 T
MARK WAIT
SUBI T 1 T
TJMP WAIT

TEST M = X
DIVI 0 T T ;DIE ON FALSE

; TARGET FOUND!

@REP 4
KILL
@END
SEEK -9999
SEEK 1
COPY 10 T
MARK WAIT2
SUBI T 1 T
TJMP WAIT2

COPY M X
MARK FINDLOCKED
TEST F = X
TJMP FOUNDLOCKED
SEEK 2
JUMP FINDLOCKED

MARK FOUNDLOCKED
COPY M F

SEEK -9999
SEEK 1
COPY M X
MARK FINDSAFE
TEST F = X
TJMP FOUNDSAFE
SEEK 2
JUMP FINDSAFE

MARK FOUNDSAFE
COPY F M

SEEK -9999
SEEK 1
COPY M X
MARK FINDCLOCK
TEST F = X
TJMP FOUNDCLOCK
SEEK 2
JUMP FINDCLOCK

MARK FOUNDCLOCK
COPY M F

HALT

; MUTEX HIDEOUT

MARK FOUNDTALISMAN
COPY M X
SEEK -9999
SEEK 1
MARK FINDMAP
TEST F = X
TJMP FOUNDMAP
SEEK 2
JUMP FINDMAP

MARK FOUNDMAP
COPY F M

COPY M X
SEEK -9999
SEEK 1
MARK FINDUNLOCKED
TEST F = X
TJMP FOUNDUNLOCKED
SEEK 2
JUMP FINDUNLOCKED

MARK FOUNDUNLOCKED
COPY F M
195/108/11.

The start works as before. TALISMAN is sent to XB before it REPLs. Then each instance goes looking for it. The ones that do NOT find it go into a wait loop (29 iterations seemed to work), so they don't try reading from M before everything is ready.

The one that does find it jumps to FOUNDTALISMAN, gets the MAP keyword from XA, finds the target's location, sens that to XA, gets the DOOR from XA, and sends UNLOCKED to XA. During this time the other EXAs are spinning their wheels.

Now, XA sends the target hostname 5 times, so that every other XB instance can check if they're there. The correct EXA kills the vampires, then waits some more until every other EXA read the target host, gets the DOOR and UNLOCKED from XA and updates the file. Then it runs the same code to copy the safe's combination to the clock as before.


And that's it for my optimizations. I'll leave further improvements to you.



There's no dialogue, just a checkmark. I have been told that there will be more plot later on, but for now, I'll just continue doing tasks.